package com.niiwoo.civet.user.service.duboo;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.niiwoo.activity.event.constant.BizEventRabbitConstant;
import com.niiwoo.activity.event.dto.request.RegisterEventReqDTO;
import com.niiwoo.activity.stage.dto.request.channel.DraingeChannelUseAddReqDTO;
import com.niiwoo.activity.stage.service.channel.DraingeChannelDubboService;
import com.niiwoo.civet.system.service.SysParamService;
import com.niiwoo.civet.user.dao.entity.*;
import com.niiwoo.civet.user.dao.mapper.AccountExtendMapperExt;
import com.niiwoo.civet.user.dao.mapper.LoginAccountMappingMapper;
import com.niiwoo.civet.user.dao.mapper.UserBasicInfoMapperExt;
import com.niiwoo.civet.user.dao.mapper.UserNickNameLibraryMapper;
import com.niiwoo.civet.user.dto.request.AutoRegisterFltDto;
import com.niiwoo.civet.user.dto.response.FltUserAutoRegisterDto;
import com.niiwoo.civet.user.dto.response.UserAutoRegisterDto;
import com.niiwoo.civet.user.enums.TCFromTypeEnum;
import com.niiwoo.civet.user.enums.UserEnum;
import com.niiwoo.civet.user.service.FltUserLoginDubboService;
import com.niiwoo.civet.user.service.local.*;
import com.niiwoo.civet.user.service.local.dataflow.UserDataBackFlowService;
import com.niiwoo.civet.user.service.local.sms.SMSSenders;
import com.niiwoo.tripod.base.component.PrivacyMasks;
import com.niiwoo.tripod.base.helper.StringHelper;
import com.niiwoo.tripod.im.component.IMService;
import com.niiwoo.tripod.im.request.UpdateUserInfoRequest;
import com.niiwoo.tripod.im.response.NiiwooNumberResponse;
import com.niiwoo.tripod.service.component.SnowflakeIdWorker;
import com.niiwoo.tripod.tiancheng.request.df.RegisterSuccessRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

/**
 * 用户登录账号API实现
 */
@Service(version = "1.0.0")
@Slf4j
public class FltUserLoginDubboServiceImpl implements FltUserLoginDubboService {
    @Autowired
    UserLoginAccountService userLoginAccountLocalService;

    @Autowired
    SnowflakeIdWorker snowflakeIdWorker;

    @Autowired
    UserForbidService userForbidService;

    @Autowired
    PrivacyMasks privacyMasks;

    @Reference(version = "1.0.0")
    SysParamService sysParamService;

    @Autowired
    UserDataBackFlowService userDataBackFlowService;

    @Autowired
    UserBasicInfoService userBasicInfoService;

    @Autowired
    IMService imService;

    @Autowired
    UserStatusService userStatusService;

    @Autowired
    IdentityMappingService identityMappingService;

    @Autowired
    UserIdentityService userIdentityService;

    @Autowired
    AccountExtendMapperExt accountExtendMapperExt;

    @Autowired
    UserBasicInfoMapperExt userBasicInfoMapperExt;

    @Autowired
    LoginAccountMappingMapper loginAccountMappingMapper;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private UserNickNameLibraryMapper userNickNameLibraryMapper;

    @Autowired
    SMSSenders smsSender;

    @Reference(version = "1.0.0")
    DraingeChannelDubboService draingeChannelDubboService;


    /**
     * 加密手机号
     *
     * @param mobileNo 手机号
     */
    private String getEncryptMobileNo(String mobileNo) {
        return privacyMasks.encryptPrivacy(mobileNo);
    }
    /**
     * 返利投渠道自动注册用户
     * @param registerRequest
     * @return
     */
    @Override
    public FltUserAutoRegisterDto autoRegisterByFlt(AutoRegisterFltDto registerRequest) {
        log.info("返利投用户注册，用户信息为:{}", JSON.toJSONString(registerRequest));
        FltUserAutoRegisterDto result = new FltUserAutoRegisterDto(FltUserAutoRegisterDto.SUCCESS_RET, FltUserAutoRegisterDto.SUCCESS_RET_MSG);
        // 注册来源不能为空
        if (registerRequest.getRegisterChannel() == null) {
            result.setRet(UserAutoRegisterDto.FAIL_RET);
            result.setMessage("注册来源不能为空");
            return result;
        }
        String userId;
        String nickName = "";
        // 加密登录手机号
        final String encryptMobileNo = getEncryptMobileNo(registerRequest.getLoginMobileNo());
        // 校验用户是否存在
        LoginAccountMapping loginAccountMapping = userLoginAccountLocalService.getAccountMapping(encryptMobileNo);
        if (loginAccountMapping == null) {
            log.info("返利投用户{}不存在，第一次推送信息",registerRequest.getLoginMobileNo());
            AutoRegisterFltDto regRequest = new AutoRegisterFltDto();
            BeanUtils.copyProperties(registerRequest,regRequest);
            userId = autoRegist(regRequest, encryptMobileNo);
            // 失败
            if (String.valueOf(UserAutoRegisterDto.FAIL_RET).equals(userId)) {
                result.setRet(UserAutoRegisterDto.FAIL_RET);
                result.setMessage("注册失败");
                result.setErrorCode(UserAutoRegisterDto.ERROR_CODE_REGIST);
                return result;
            }
            //添加返利投用户信息
            FltFundChannel fltFundChannel = new FltFundChannel();
            fltFundChannel.setMobileNo(encryptMobileNo);
            fltFundChannel.setUserId(userId);
            fltFundChannel.setRegisterToken(registerRequest.getRegisterToken());
            fltFundChannel.setCreateTime(new Date());
            fltFundChannel.setUid(registerRequest.getUid());
            userLoginAccountLocalService.initFltUserInfo(fltFundChannel);
            UserBasicInfo userBasicInfo = userLoginAccountLocalService.selectUserBasicInfo(userId);
            nickName = userBasicInfo.getNickName();
            log.info("返利投用户{}数据第一次推送信息，数据插入成功",registerRequest.getLoginMobileNo());
        } else {
            log.info("返利投用户手机号已存在");
            result.setRet(FltUserAutoRegisterDto.USER_EXIT);
            result.setMessage("注册失败，用户已存在");
            result.setErrorCode(UserAutoRegisterDto.ERROR_CODE_REGIST);
            userId = loginAccountMapping.getUserId();
        }
        result.setData(nickName);

        return result;

    }

    /**
     * 随机获取一张系统头像作为默认头像
     *
     * @return 头像URL
     */
    private String randomGetSystemHeader() {
        return "";
    }

    /**
     * 随机生成昵称
     *
     * @return 昵称
     */
    private String generateNiiwooNickname() {
        return "niiwoo" + StringHelper.genRandomStr(10);
    }

    /**
     * 保存拉取IM的用户你我号
     */
    private String updateUserInfoIM(UpdateUserInfoRequest request) {
        try {
            log.info("FltUserLoginDubboServiceImpl updateUserInfoIM request={}", request.getGuid());
            CompletableFuture<NiiwooNumberResponse> completableFuture = imService.updateUserInfo(request);
            NiiwooNumberResponse niiwooNumberResponse = completableFuture.get(5, TimeUnit.SECONDS);
            log.info("FltUserLoginDubboServiceImpl updateUserInfoIM response={}", JSON.toJSON(niiwooNumberResponse));
            //返回码code: 1失败，0成功
            if (niiwooNumberResponse.getCode() == 0) {
                return String.valueOf(niiwooNumberResponse.getImid());
            } else {
                log.error("用户注册###获取你我号###失败: userId={}", request.getGuid());
            }
        } catch (Exception e) {
            log.error(String.format("用户注册###获取你我号###异常: userId=%s, error=%s", request.getGuid(), e.getMessage()), e);
        }
        return "";
    }


    /**
     * 返利投自动注册
     *
     * @param registerRequest
     * @param encryptMobileNo
     * @return
     */
    private String autoRegist(AutoRegisterFltDto registerRequest, String encryptMobileNo) {
        // 初始化用户相关信息并保存
        Date now = new Date();
        String userId = UUID.randomUUID().toString();
        // 账号映射
        LoginAccountMapping accountMapping = new LoginAccountMapping();
        accountMapping.setAccountName(encryptMobileNo);
        accountMapping.setUserId(userId);
        // 账号
        UcAccount account = new UcAccount();
        account.setUserId(userId);
        account.setMobileNo(encryptMobileNo);
        account.setSalt(registerRequest.getSalt());
        account.setPassword(registerRequest.getPassword());
        account.setCreateTime(now);
        // 基础信息
        UserBasicInfo basicInfo = new UserBasicInfo();
        basicInfo.setUserId(userId);
        basicInfo.setMobileNo(encryptMobileNo);
        basicInfo.setRegisterChannel(registerRequest.getRegisterChannel().getValue());
        basicInfo.setNiiwooScore(300); //初始化用户你我分为300
        final String nickName = generateNiiwooNickname();
        basicInfo.setNickName(nickName);
        basicInfo.setHeadImage(randomGetSystemHeader());
        basicInfo.setGender((byte) UserEnum.Gender.UNKNOWN.getValue());
        basicInfo.setPersonalSign("");
        basicInfo.setCreateTime(now);
        basicInfo.setIdentityTag(UserEnum.IdentityTag.NO_IDENTITY.getType());
        //注册拉取你我号
        UpdateUserInfoRequest request = new UpdateUserInfoRequest();
        request.setGuid(userId);
        request.setNickname(nickName);
        request.setMobile(registerRequest.getLoginMobileNo());
        request.setAvatar(randomGetSystemHeader());
        request.setGender((byte)UserEnum.Gender.UNKNOWN.getValue());
        request.setPassword(registerRequest.getPassword());
        basicInfo.setNiiwooCode(updateUserInfoIM(request));
        // 扩展信息(融360用户未在app直接注册，无其他信息)
        UserExtInfo extInfo = new UserExtInfo();
        extInfo.setUserId(userId);
        extInfo.setCreateTime(new Date());
        // 认证信息
        UserAuthorizationInfo authorizationInfo = new UserAuthorizationInfo();
        authorizationInfo.setUserId(userId);
        authorizationInfo.setZhimaScore(registerRequest.getZhiMa());
        authorizationInfo.setZhimaFailureReason("");
        authorizationInfo.setSocialSecurityAuthCity(registerRequest.getInsureCity());
        authorizationInfo.setFadadaCacertId("");
        authorizationInfo.setCreateTime(now);
        //你我分
        NiiwooScore score = new NiiwooScore();
        score.setId(snowflakeIdWorker.nextId());
        score.setUserId(userId);
        score.setScore(300);
        score.setScoreDetail("{'EngagementAbility':'0','CreditHistory':'0','GuanXi':'0','Behavior':'0','IdFeature':'0'}");
        score.setEvaluateTime(new Date());
        score.setCreateTime(new Date());
        score.setEvaluateTime(new Date());
        boolean isSuccess = userLoginAccountLocalService.initAccountAndBasicInfo(accountMapping, account, basicInfo,authorizationInfo,score,extInfo);

        if (isSuccess) {
            // 渠道引流
            CompletableFuture.supplyAsync(() -> {
                DraingeChannelUseAddReqDTO channelUseAddReqDTO = new DraingeChannelUseAddReqDTO();
                channelUseAddReqDTO.setUserId(accountMapping.getUserId());
                channelUseAddReqDTO.setLinkAddress(registerRequest.getLinkAddress());
                log.info("注册成功###用户引流###请求, requset={}", JSON.toJSONString(channelUseAddReqDTO));
                draingeChannelDubboService.addDraingeChannelUse(channelUseAddReqDTO);
                return true;
            }).whenComplete((success, throwable) -> {
                if (throwable != null) {
                    log.error(String.format("注册成功###用户引流###异常, errorMessage=%s", throwable.getMessage()), throwable);
                } else {
                    log.info("注册成功###用户引流###成功, result=={}", success);
                }
            });

            //注册事件，发送MQ消息
            CompletableFuture.runAsync(() -> {
                try {
                    RegisterEventReqDTO eventReqDTO = new RegisterEventReqDTO();
                    eventReqDTO.setMobileNo(registerRequest.getLoginMobileNo());
                    eventReqDTO.setChannelSource(registerRequest.getChannelCode());
                    eventReqDTO.setRegisterDate(new Date());
                    eventReqDTO.setRegisterAddress(extInfo.getRegisterAddress());
                    eventReqDTO.setAppVersion("");
                    eventReqDTO.setPhoneModel("");
                    eventReqDTO.setUserId(String.valueOf(accountMapping.getUserId()));
                    eventReqDTO.setUpdateDate(new Date());
                    rabbitTemplate.convertAndSend(
                            BizEventRabbitConstant.Exchange.BIZ_EVENT_DIRECT_EXCHANGE,
                            BizEventRabbitConstant.Key.BIZ_EVENT_REGISTER_KEY,
                            eventReqDTO
                    );
                    log.info("【注册事件】消息发送成功，RegisterEventReqDTO:{}", JSON.toJSONString(eventReqDTO));
                } catch (Exception e) {
                    log.error("【注册事件】消息发送失败，userId:{}", accountMapping.getUserId(), e);
                }
                // 天秤数据回流
                RegisterSuccessRequest registerSuccessRequest = new RegisterSuccessRequest();
                registerSuccessRequest.setUserId(String.valueOf(userId));
                registerSuccessRequest.setUserNickName(basicInfo.getNickName());
                registerSuccessRequest.setUserAccount(basicInfo.getNiiwooCode());
                registerSuccessRequest.setAvatar(basicInfo.getHeadImage());
                registerSuccessRequest.setUserName(registerRequest.getLoginMobileNo());
                registerSuccessRequest.setMobilePhone(registerRequest.getLoginMobileNo());
                ////用户来源(0-未知 1团贷网，2好帮贷，3你我金融，4房宝宝，5现金动车，6量化派 7 借钱快 8 融360 9卡牛)
                registerSuccessRequest.setFromType(TCFromTypeEnum.getTCFromTypeFromRegisterChannel(registerRequest.getRegisterChannel()));
                registerSuccessRequest.setRegisterTime(System.currentTimeMillis() * 1000L);
                userDataBackFlowService.regiserSuccess(registerSuccessRequest);
                });

        }
        return isSuccess ? userId : String.valueOf(UserAutoRegisterDto.FAIL_RET);
    }

    /**
     * 查询返利投用户注册关系
     * @param autoRegisterFltDto
     * @return
     */
    @Override
    public FltUserAutoRegisterDto queryRegisterRelation(AutoRegisterFltDto autoRegisterFltDto) {
        FltUserAutoRegisterDto result = new FltUserAutoRegisterDto(FltUserAutoRegisterDto.SUCCESS_RET, FltUserAutoRegisterDto.SUCCESS_RET_MSG);
        final String encryptMobileNo = getEncryptMobileNo(autoRegisterFltDto.getLoginMobileNo());
        FltFundChannel fltFundChannel = userLoginAccountLocalService.selectFltFundByUidAndToken(autoRegisterFltDto.getUid(),null);
        String userId = "";
        if (fltFundChannel == null){
            userId = userBasicInfoService.queryUserIdByMobileNo(encryptMobileNo);
        }else {
            userId = fltFundChannel.getUserId();
        }


        if (fltFundChannel != null){
            UserBasicInfo userBasicInfo= userBasicInfoService.selectUserBasicInfo(userId);
            Map<String,String> dataMap = new HashMap<String, String>();
            dataMap.put("user_name",userBasicInfo.getNickName());
            dataMap.put("register_token",fltFundChannel.getRegisterToken());
            result.setRet(12); //返利投渠道用户
            result.setData(dataMap);
        }else if(fltFundChannel == null && StringUtils.isEmpty(userId)){
            result.setRet(10);
            result.setMessage("未注册");
        }else if(fltFundChannel == null && !StringUtils.isEmpty(userId)){
            result.setRet(13);//老用户，其他渠道用户
            result.setMessage("老用户，其他渠道用户");
        }
        return result;
    }

    /**
     * 获取token
     * @param uid
     * @param register_token
     * @return
     */
    @Override
    public String getUserId(String uid, String register_token) {
        String userId = null;
        FltFundChannel fltFundChannel = userLoginAccountLocalService.selectFltFundByUidAndToken(uid,register_token);
        if (fltFundChannel != null){
            userId = fltFundChannel.getUserId();
        }
        return userId;
    }
}
